package concurrent.juc.reentrantlock;

import java.util.concurrent.locks.ReentrantLock;

/**
 * @author: 黄嘉振
 * @create: 2023/6/15 14:48
 * @description:    可重入锁
 **/
public class ReentrantLockDemo {
    static int num;

    public static void main(String[] args) throws InterruptedException {
        CountTask task = new CountTask();
        Thread thread1 = new Thread(task);
        Thread thread2 = new Thread(task);
        thread1.start();
        thread2.start();
        thread1.join();
        thread2.join();
        System.out.println("num: " + num);
    }

    static class CountTask implements Runnable {
        private ReentrantLock lock = new ReentrantLock();

        /**
         * 一个线程允许反复进⼊
         * 同⼀个线程多次获锁，那么在释放锁的时候，也必须释放相同次数
         */
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName() + " start !");
            for (int i = 0; i < 100000; i++) {
                lock.lock();
                // 释放次数少，则还是持有该有
//                lock.lock();
                try {
                    num++;
                } finally {
                    lock.unlock();
                }
                // 释放次数多，抛出异常 java.lang.IllegalMonitorStateException
//                lock.unlock();
            }
            System.out.println(Thread.currentThread().getName() + " end !");
        }
    }
}
